package RedHead;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.Timer;

import RedHeadGUI.Gui;

import com.jme3.animation.AnimChannel;
import com.jme3.animation.AnimControl;
import com.jme3.animation.AnimEventListener;
import com.jme3.animation.LoopMode;
import com.jme3.app.Application;
import com.jme3.app.SimpleApplication;
import com.jme3.app.state.AppStateManager;
import com.jme3.input.KeyInput;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.niftygui.NiftyJmeDisplay;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Quad;
import com.jme3.system.AppSettings;
import com.jme3.texture.Texture;

import de.lessvoid.nifty.Nifty;

/**
 * 
 * @author Holger Hanson
 */

public class Main extends SimpleApplication implements AnimEventListener {
	private AnimChannel channel;
	private AnimControl control;
	Node redHead;
	Controler steuerung;
	private Gui startScreen;
	public static Main app;
	Timer timer;

	/**
	 * Main-Methode die das Programm startet
	 * 
	 * @param args
	 * 
	 */
	public static void main(String[] args) {
		AppSettings settings = new AppSettings(true);
		settings.setResolution(1280, 720);
		app = new Main();
		app.setShowSettings(false); // splashscreen
		app.setSettings(settings);
		app.start();
	}

	/**
	 * Startet GUI und Screenmanager
	 */
	private final void startGui() {
		setDisplayFps(false);
		setDisplayStatView(false);
		startScreen = new Gui();
		stateManager.attach(startScreen);
		NiftyJmeDisplay niftyDisplay = new NiftyJmeDisplay(assetManager,
				inputManager, audioRenderer, guiViewPort);
		Nifty nifty = niftyDisplay.getNifty();
		guiViewPort.addProcessor(niftyDisplay);
		nifty.fromXml("Interface/RedHeadGUI/readHeadViewer.xml", "start",
				startScreen);
		flyCam.setDragToRotate(true);

	}

	/**
	 * Programm wird geschlossen
	 */
	public void quitGame() {
		app.stop();
	}

	public static final String getDirectory() {
		String directory = System.getProperty("user.dir");
		return directory;
	}

	@Override
	public void simpleInitApp() {
		startGui();
		Map<Integer, String> zuordnung = new HashMap<Integer, String>();
		zuordnung.put(KeyInput.KEY_W, "walk");
		zuordnung.put(KeyInput.KEY_S, "walk_back");
		zuordnung.put(KeyInput.KEY_0, "0");
		zuordnung.put(KeyInput.KEY_1, "1");
		zuordnung.put(KeyInput.KEY_2, "2");
		zuordnung.put(KeyInput.KEY_3, "3");
		zuordnung.put(KeyInput.KEY_4, "4");
		zuordnung.put(KeyInput.KEY_5, "5");
		zuordnung.put(KeyInput.KEY_6, "6");
		zuordnung.put(KeyInput.KEY_7, "7");
		zuordnung.put(KeyInput.KEY_8, "8");
		zuordnung.put(KeyInput.KEY_9, "9");
		steuerung = new Controler(this, zuordnung);

		// Set background color
		viewPort.setBackgroundColor(ColorRGBA.White);

		flyCam.setEnabled(false);

		Node root = new Node("root");
		rootNode.attachChild(root);
		Node pivot = new Node("pivot");
		root.attachChild(pivot);

		redHead = (Node) assetManager
				.loadModel("Models/redHead/redHead.mesh.xml");
		redHead.scale(0.025f, 0.025f, 0.025f);

		redHead.setLocalTranslation(0f, -4f, 0f);

		pivot.attachChild(redHead);

		control = redHead.getControl(AnimControl.class);
		control.addListener(this);
		channel = control.createChannel();
		channel.setAnim("stehen");

		DirectionalLight sun = new DirectionalLight();
		sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
		rootNode.addLight(sun);

		cam.setLocation(new Vector3f(0, 3, 22));

		// initialisiere Raum
		initializeGym();

		// starte Timer fuer Langeweile
		startTimer();
	}

	@Override
	public void simpleUpdate(float tpf) {

	}

	@Override
	public void simpleRender(RenderManager rm) {

	}

	public float getSpeed() {
		return speed;
	}

	public AnimChannel getChannel() {
		return channel;
	}

	@Override
	public void onAnimChange(AnimControl arg0, AnimChannel arg1, String arg2) {

	}

	/**
	 * (geschrieben von Katharina Gausmann)
	 * 
	 * Steuert welche Animation als naechstes gestartet werden muss, Anhand der
	 * gedrueckten Taste (getAnimationKeyPressed())wird entschieden welche
	 * Animation ausgefuehrt werden muss, Sollte ein Uebergang abgeschlossen
	 * sein, so wird die anschliessende Animation gestartet, Ist keine Taste
	 * gedrueckt, wird der Uebergang zum Stand, sowie der Timer gestartet
	 */
	@Override
	public void onAnimCycleDone(AnimControl arg0, AnimChannel arg1, String arg2) {
		if (steuerung.getAnimationKeyPressed() != null) {
			if (channel.getAnimationName().contains("#")) {
				String animToDo = channel.getAnimationName().substring(
						channel.getAnimationName().indexOf("#") + 1);
				setAnimationErrorSave(animToDo);
				if (steuerung.getAnimationKeyPressed().equals("langeweile")) {
					steuerung.setAnimationKeyPressed(null);
				}
			} else {
				setAnimationErrorSave(channel.getAnimationName() + "#"
						+ steuerung.getAnimationKeyPressed());
				channel.setLoopMode(LoopMode.DontLoop);
			}
		} else {
			if (channel.getAnimationName().contains("#")) {
				String animToDo = channel.getAnimationName().substring(
						channel.getAnimationName().indexOf("#") + 1);
				setAnimationErrorSave(animToDo);
			} else {
				setAnimationErrorSave(channel.getAnimationName() + "#stehen");
				if (!timer.isRunning()) {
					startTimer();
				}

			}

		}

	}

	/**
	 * 
	 * (geschrieben von Katharina Gausmann) Setzt Animation Setzt stehen, wenn
	 * Animation die gestartet werden soll nicht gefunden wird
	 * 
	 * @param anim
	 * 
	 */
	public void setAnimationErrorSave(String anim) {
		if (control.getAnim(anim) != null) {
			channel.setAnim(anim);
		} else {
			channel.setAnim("stehen");
		}
	}

	/**
	 * (geschrieben von Katharina Gausmann)
	 * 
	 * Erzeugt und startet einen Timer zur Steuerung der Langeweile-Animation,
	 * Diese wird nach 12 Sekunden Stand automatisch aufgerufen
	 */
	private void startTimer() {
		ActionListener taskPerformer = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				steuerung.setAnimationKeyPressed("langeweile");
			}

		};
		timer = new Timer(12000, taskPerformer);
		timer.start();
	}

	public void initialize(AppStateManager stateManager, Application app) {

	}

	/**
	 * (geschrieben von Claudia Ohm) Umgebung wird erstellt (Turnhalle)
	 */
	public void initializeGym() {

		// Umgebungsknoten
		Node environment = new Node("environment");
		((Node) getRootNode().getChild("root")).attachChild(environment);
		Node boden = new Node("boden");
		environment.attachChild(boden);

		Quad floor = new Quad(700f, 500f);
		Geometry geom = new Geometry("My Textured Box", floor);
		Material mat_stl = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture tex_ml = assetManager.loadTexture("Textures/field.jpg");
		mat_stl.setTexture("m_ColorMap", tex_ml);
		geom.setMaterial(mat_stl);
		geom.setLocalTranslation(-350f, -40f, 250f);
		geom.rotate((float) (-Math.PI / 2), 0f, 0f);
		boden.attachChild(geom);

		// Decke
		Quad ceiling = new Quad(700f, 500f);
		Geometry geomceiling = new Geometry("ceiling", ceiling);
		Material matceiling = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texceiling = assetManager.loadTexture("Textures/ceiling.jpg");
		matceiling.setTexture("m_ColorMap", texceiling);
		geomceiling.setMaterial(matceiling);
		geomceiling.setLocalTranslation(-350f, 249f, -250f);
		geomceiling.rotate((float) (Math.PI / 2), 0f, 0f);
		environment.attachChild(geomceiling);

		Box b = new Box(new Vector3f(0f, 68f, 0f), -350f, -150f, -250f);
		Geometry g = new Geometry("Box", b); // create cube geometry from the
												// shape
		Material mat = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple
														// material
		Texture tex_ml2 = assetManager.loadTexture("Textures/wall.JPG");
		mat.setTexture("m_ColorMap", tex_ml2);
		g.setMaterial(mat); // set the cube's material

		environment.attachChild(g);

		Quad door = new Quad(120f, 100f);
		Geometry geomdoor = new Geometry("door", door);
		Material matdoor = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texdoor = assetManager.loadTexture("Textures/door.jpg");
		matdoor.setTexture("m_ColorMap", texdoor);
		geomdoor.setMaterial(matdoor);
		geomdoor.setLocalTranslation(-60f, -40f, -249f);
		environment.attachChild(geomdoor);

		// Matten

		Quad matte = new Quad(120f, 80f);
		Geometry geommatte = new Geometry("matte", matte);
		Material matmatte = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texmatte = assetManager.loadTexture("Textures/Matte.jpg");
		matmatte.setTexture("m_ColorMap", texmatte);
		geommatte.setMaterial(matmatte);
		geommatte.setLocalTranslation(-240f, -44f, -249f);
		environment.attachChild(geommatte);

		Quad matte2 = new Quad(120f, 80f);
		Geometry geommatte2 = new Geometry("matte2", matte2);
		Material matmatte2 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texmatte2 = assetManager.loadTexture("Textures/Matte.jpg");
		matmatte2.setTexture("m_ColorMap", texmatte2);
		geommatte2.setMaterial(matmatte2);
		geommatte2.setLocalTranslation(120f, -44f, -249f);
		environment.attachChild(geommatte2);

		Quad matte3 = new Quad(120f, 80f);
		Geometry geommatte3 = new Geometry("matte3", matte3);
		Material matmatte3 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texmatte3 = assetManager.loadTexture("Textures/Matte.jpg");
		matmatte3.setTexture("m_ColorMap", texmatte3);
		geommatte3.setMaterial(matmatte3);
		geommatte3.rotate(0f, (float) (Math.PI), 0f);
		geommatte3.setLocalTranslation(250f, -44f, 249f);
		environment.attachChild(geommatte3);

		Quad matte4 = new Quad(120f, 80f);
		Geometry geommatte4 = new Geometry("matte4", matte4);
		Material matmatte4 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texmatte4 = assetManager.loadTexture("Textures/Matte.jpg");
		matmatte4.setTexture("m_ColorMap", texmatte4);
		geommatte4.setMaterial(matmatte3);
		geommatte4.rotate(0f, (float) (Math.PI), 0f);
		geommatte4.setLocalTranslation(-120f, -44f, 249f);
		environment.attachChild(geommatte4);

		// Koerbe
		Quad korb = new Quad(80f, 80f);
		Geometry geomkorb = new Geometry("korb", korb);
		Material matkorb = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texkorb = assetManager.loadTexture("Textures/korb.jpg");
		matkorb.setTexture("m_ColorMap", texkorb);
		geomkorb.setMaterial(matkorb);
		geomkorb.rotate(0f, (float) (-Math.PI / 2), 0f);
		geomkorb.setLocalTranslation(349f, 20f, -40f);
		environment.attachChild(geomkorb);

		Quad korb2 = new Quad(80f, 80f);
		Geometry geomkorb2 = new Geometry("korb2", korb2);
		Material matkorb2 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texkorb2 = assetManager.loadTexture("Textures/korb.jpg");
		matkorb2.setTexture("m_ColorMap", texkorb2);
		geomkorb2.setMaterial(matkorb2);
		geomkorb2.rotate(0f, (float) (Math.PI / 2), 0f);
		geomkorb2.setLocalTranslation(-349f, 20f, 40f);
		environment.attachChild(geomkorb2);

		// Fenster
		Quad window = new Quad(200f, 80f);
		Geometry geomwindow = new Geometry("window", window);
		Material matwindow = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texwindow = assetManager.loadTexture("Textures/window.jpg");
		matwindow.setTexture("m_ColorMap", texwindow);
		geomwindow.setMaterial(matwindow);
		geomwindow.setLocalTranslation(-280f, 100f, -249f);
		environment.attachChild(geomwindow);

		Quad window2 = new Quad(200f, 80f);
		Geometry geomwindow2 = new Geometry("window2", window2);
		Material matwindow2 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texwindow2 = assetManager.loadTexture("Textures/window.jpg");
		matwindow2.setTexture("m_ColorMap", texwindow2);
		geomwindow2.setMaterial(matwindow2);
		geomwindow2.setLocalTranslation(80f, 100f, -249f);
		environment.attachChild(geomwindow2);

		Quad window3 = new Quad(200f, 80f);
		Geometry geomwindow3 = new Geometry("window3", window3);
		Material matwindow3 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texwindow3 = assetManager.loadTexture("Textures/window.jpg");
		matwindow3.setTexture("m_ColorMap", texwindow3);
		geomwindow3.setMaterial(matwindow3);
		geomwindow3.rotate(0f, (float) (Math.PI), 0f);
		geomwindow3.setLocalTranslation(290f, 100f, 249f);
		environment.attachChild(geomwindow3);

		Quad window4 = new Quad(200f, 80f);
		Geometry geomwindow4 = new Geometry("window4", window4);
		Material matwindow4 = new Material(assetManager,
				"Common/MatDefs/Misc/Unshaded.j3md");
		Texture texwindow4 = assetManager.loadTexture("Textures/window.jpg");
		matwindow4.setTexture("m_ColorMap", texwindow4);
		geomwindow4.setMaterial(matwindow4);
		geomwindow4.rotate(0f, (float) (Math.PI), 0f);
		geomwindow4.setLocalTranslation(-80f, 100f, 249f);
		environment.attachChild(geomwindow4);
		environment.scale(0.1f);

	}

}
